// ****************************************************************************
//	Copyright (c) 2011 Daniel Watman
//	http://www.keycommander.net/
// ****************************************************************************
//	This program is free software: you can redistribute it and/or modify
//	it under the terms of the GNU General Public License as published by
//	the Free Software Foundation, either version 3 of the License, or
//	(at your option) any later version.
//	
//	This program is distributed in the hope that it will be useful,
//	but WITHOUT ANY WARRANTY; without even the implied warranty of
//	 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//	GNU General Public License for more details.
//	
//	You should have received a copy of the GNU General Public License
//	along with this program.  If not, see <http://www.gnu.org/licenses/>.
// ****************************************************************************
//	File: btn_test.c
//	Purpose: test of conversion of PNG images to LCD image format
//	Author:	Daniel Watman
//	Created: 2011.02.18
//	Updated: 2011.02.24
//	Version: 0.2
//	Target:	linux (but standard C/C++ should work on anything?)
//	Compiler: GCC (but standard C/C++ should work on anything?)
// ****************************************************************************
//	Changes:
//		0.1	* Initial version. Conversion mostly works but display on button is scrambled
//		0.2	* Conversion fixed, display on button is perfect
// ****************************************************************************
//	To do:
//		* Write converted data to file
// ****************************************************************************
//	Comments:
//		* This program uses LodePNG by Lode Vandevenne for PNG reading
//		* This is just a test, move parts into the main KeyCommander programs later
// ****************************************************************************

#include <stdlib.h>
#include <stdio.h>
//#include <stdio.h>
#include "lodepng.h"

int main(int argc, char *argv[]) {
	const char* filename = argc > 1 ? argv[1] : "test.png";
	unsigned char* grey; // greyscale image
	size_t i, greysize;
	int row, col;
	unsigned char* buffer; //file
	size_t buffersize;
	LodePNG_Decoder decoder;
	unsigned char LCDimg[256];
	unsigned char byte, bit;
	unsigned int tmp;

	// load and decode
	LodePNG_loadFile(&buffer, &buffersize, filename); // load the image file with given filename
	LodePNG_Decoder_init(&decoder);
	LodePNG_Decoder_inspect(&decoder, buffer, buffersize); // get information from the header, to see if it's greyscale

	if(!decoder.error) {
		printf("Image size: %dx%d\n", decoder.infoPng.width, decoder.infoPng.height);
		printf("bitDepth: %d, ", decoder.infoPng.color.bitDepth);
		printf("bpp: %d, ", LodePNG_InfoColor_getBpp(&decoder.infoPng.color));
		printf("colorChannels: %d\n", LodePNG_InfoColor_getChannels(&decoder.infoPng.color));
		printf("paletteSize: %d\n", (int)decoder.infoPng.color.palettesize);
		printf("colorType: %d\n", decoder.infoPng.color.colorType);

		if(LodePNG_InfoColor_isGreyscaleType(&decoder.infoPng.color)) {	//if the PNG image is greyscale, can the output be converted to greyscale by LodePNG 
			printf("Image is greyscale\n");
			decoder.infoRaw.color.colorType = 0; //set color type "greyscale" for the output
			LodePNG_Decoder_decode(&decoder, &grey, &greysize, buffer, buffersize);
		}
		else {//else convert to greyscale
			unsigned char* rgb; //temporary rgb image
			size_t rgbsize;

			printf("Image is colour\n");
			decoder.infoRaw.color.colorType = 2; //set color type "RGB" for the output
			LodePNG_Decoder_decode(&decoder, &rgb, &rgbsize, buffer, buffersize);

			greysize = rgbsize / 3;
			grey = (unsigned char*)malloc(greysize);
			for(i = 0; i < greysize; i++) grey[i] = (rgb[i * 3 + 0] + rgb[i * 3 + 1] + rgb[i * 3 + 2]) / 3; //rgb to greyscale by taking average
			free(rgb);
		}

		// encode the image data into the LCD memory format
		for (i=0;i<256;i++) LCDimg[i] = 0x00;	// start by clearing all pixels

		// display in ASCII art
		for (row=0;row<32;row++) {
			for (col=0;col<64;col++) {
				if (grey[col+row*64] < 128) printf(" ");
				else printf ("O");
			}
			printf("\n");
		}
		// threshold and encode
		for (row=0;row<32;row++) {
			for (col=0;col<64;col++) {
				if (grey[col+row*64] > 128) continue;	// skip if pixel is white (pixels started clear)

				if (row < 16)	tmp = (63-col)*32+row+16;	// bit number 0-2047 (top half of image)
				else 			tmp = (63-col)*32+row-16;	// bit number 0-2047 (bottom half of image)
				
				byte = tmp>>3;		// byte number (0-255)
				bit = tmp - byte*8;	//bit number starting at LSB (0-7)
				LCDimg[byte] |= (1<<bit);	// set the appropriate bit
			}
		}
		// display in C array declaration format
		printf("\nu08 img[256] = {");
		for (i=0;i<256;i++) {
			printf ("0x%02X", LCDimg[i]);
			if (i == 255) printf("};");
			else printf(", ");
			if ((i%8) == 7) printf("\t// col %u, %u\n", (unsigned int)i/4-1, (unsigned int)i/4);
		}
		printf("\n");
	}

	if(decoder.error) printf("error %u: %s\n", decoder.error, LodePNG_error_text(decoder.error));
	else printf("read %d greyscale pixels\n", (int)greysize);

	//cleanup decoder
	free(grey);
	free(buffer);
	LodePNG_Decoder_cleanup(&decoder);

	test(argc, argv);

	return 0;
}
